package ru.ifmo.swing.genetics.automaton;

import org.uncommons.watchmaker.swing.NumericParameterControl;
import ru.ifmo.automaton.Automaton;
import ru.ifmo.automaton.generators.random.RandomSynchronizingAutomatonGenerator;
import ru.ifmo.common.Source;
import ru.ifmo.swing.EvolutionControlWithConfigProvider;
import ru.ifmo.swing.Panel;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;

/**
 * @author avhaliullin
 */
public class RandomAutomatonControl implements Source<Automaton<Character, String>>, EvolutionControlWithConfigProvider {
    private final NumericParameterControl<Integer> statesCountControl;
    private final NumericParameterControl<Integer> alphabetSizeControl;
    private final Panel control;
    private final RandomSynchronizingAutomatonGenerator automatonSource;

    public RandomAutomatonControl(int minStates, int maxStates, int defaultStates, int step) {
        control = new Panel();
        control.setHorizontal(false);
        alphabetSizeControl = new NumericParameterControl<Integer>(1, 26, 1, 2);
        alphabetSizeControl.getControl().setMaximumSize(new Dimension(100, 20));

        statesCountControl = new NumericParameterControl<Integer>(minStates, maxStates, step, defaultStates);
        statesCountControl.getControl().setMaximumSize(new Dimension(100, 20));

        automatonSource = new RandomSynchronizingAutomatonGenerator(statesCountControl.getNumberGenerator(),
                alphabetSizeControl.getNumberGenerator());

        Panel p1 = new Panel();
        p1.setHorizontal(true);
        p1.setTitle("States count:");
        p1.add(statesCountControl.getControl());

        Panel p2 = new Panel();
        p2.setHorizontal(true);
        p2.setTitle("Alphabet size:");
        p2.add(alphabetSizeControl.getControl());

        control.add(p1);
        control.add(p2);

        JButton rebuildButton = new JButton("Rebuild");
        rebuildButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                automatonSource.rebuild();
            }
        });
        control.add(rebuildButton);
    }

    public JComponent getControl() {
        return control;
    }

    public void reset() {
        if (statesCountControl != null) {
            statesCountControl.reset();
        }
    }

    public void setDescription(String description) {
        control.setTitle(description);
    }

    public Automaton<Character, String> create() {
        return automatonSource.create();
    }

    public Map<String, Object> getParamValues() {
        Map<String, Object> res = new HashMap<String, Object>();
        res.put("States count", statesCountControl.getNumberGenerator().nextValue());
        res.put("Alphabet size", alphabetSizeControl.getNumberGenerator().nextValue());
        return res;
    }
}
